<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>Government Names</title>
		<script src="jquery.js"></script>
		<script src="jsrender.js"></script>

		<!--Load the AJAX API-->
		<script type="text/javascript" src="https://www.google.com/jsapi"></script>
		<script type="text/javascript">

			// Load the Visualization API library and the piechart library.
			google.load('visualization', '1.0', {'packages':['corechart']});
			//google.setOnLoadCallback(drawChart);
			// ... draw the chart...

			// Callback that creates and populates a data table,
			// instantiates the pie chart, passes in the data and
			// draws it.
			function drawChart() {
				var names = ['Year'];
				var years = [];

				for (var k = 0; k < tgd.Utilities.Names.Filtered.length; ++k) {
					var entry = tgd.Utilities.Names.Filtered[k];

					names.push(entry.Name);
					var idx = names.length - 1;
					var history = entry.History;
					for (var i = 0; i < history.length; ++i) {
					
						var exists = false;
						
						for (var j = 0; j < years.length; ++j) {
							if (years[j][0] === history[i].Year.toString()) {
								years[j][idx] = history[i].Count;
								exists = true;
							}
						}
						
						if (!exists) {
							years.push([history[i].Year.toString()]);
							years[years.length - 1][idx] = history[i].Count;
						}
					}
				}

				for (var i = 0; i < years.length; ++i) {
					for (var j = 1; j < names.length; ++j) {
						if (years[i][j] === undefined) {
							years[i][j] = 0;
						}
					}
				}

				years.sort(function(a, b) { return a[0].localeCompare(b[0]); })

				var data = google.visualization.arrayToDataTable([names].concat(years));

				var options = {
					title: 'Name Usage Per Year'
				};

				var chart = new google.visualization.LineChart(document.getElementById('panChart'));
				chart.draw(data, options);

			}

		</script>

		<script id="nameTemplate" type="text/x-jquery-tmpl">
			<div onclick="toggleNextElement(this);" class="{{:Gender}}">
				<span>{{:Name}}</span>
				<span>{{:Count}}</span>
			</div>
			<div class="history hidden">
				{{for History}}
				<div>
					<span>{{:Year}}</span>
					<span>{{:Count}}</span>
				</div>
				{{/for}}
			</div>
		</script>

		<script type="text/javascript">

			var tgd = tgd || {};
			tgd.Utilities = tgd.Utilities || {};
			tgd.Utilities.Names = tgd.Utilities.Names || {};
			tgd.Utilities.Names.GUI = tgd.Utilities.Names.GUI || {};
			tgd.Utilities.Names.All = [];
			tgd.Utilities.Names.Grouped = [];
			tgd.Utilities.Names.Filtered = [];
			tgd.Utilities.Names.Num = 0;

			function init() {
				tgd.Utilities.Names.GUI.fuNames = document.getElementById("fuNames");

				tgd.Utilities.Names.GUI.fuNames.addEventListener('change', handleFileSelect, false);

				$('#btnFilter').on("click", function() {
					displayNames();
				});
			}

			function toggleNextElement(ele) {
				while ((ele = ele.nextSibling).nodeType !== 1);

				if (ele.className.search("hidden") < 0) {
					ele.className = ele.className.concat(" hidden");
				} else {
					ele.className = ele.className.replace("hidden", "");
				}
			}

	function hidePromptScreen() {
		$("#panPrompt").fadeOut();
	}

	function handleFileSelect(evt) {
		var files = evt.target.files; // FileList object
		tgd.Utilities.Names.Num = files.length;
		console.log("Loading " + tgd.Utilities.Names.Num + " files.");
	    tgd.Utilities.Names.All = [];
	    tgd.Utilities.Names.Grouped = [];

		for ( var i = 0, f; f = files[i]; i++) {
			var reader = new FileReader();

			// Closure to capture the file information.
			reader.onload = (function(theFile) {
				return function(e) {
					var rows = e.target.result.split("\r\n");

					for ( var j = 0; j < rows.length; ++j) {
						if (rows[j] !== "") {
							var row = rows[j].split(',');
							tgd.Utilities.Names.All.push({
								Name : row[0],
								Gender : row[1],
								Count : parseInt(row[2]),
								Year : parseInt(theFile.name.match(/\d+/)[0])
							});
						}
					}

					if (--tgd.Utilities.Names.Num === 0) {
						console.log('Finished Loading Files!');
						processNames();
					} else {
						console.log(tgd.Utilities.Names.Num + ' files remaining.');
					}
				};
			})(f);

			reader.readAsText(f);
		}
	}

	function sortNames(a, b) {
	    if (a.Name.localeCompare(b.Name) === 0) {
            return a.Gender.localeCompare(b.Gender);
        } else {
            return a.Name.localeCompare(b.Name);
        }
	}
	

    function sortCount(a, b) {
        return b.Count - a.Count;
    }
    
	
	function processNames() {
		var all = tgd.Utilities.Names.All;
		console.log("Sort names");
		//Sort names by name and then by gender

		all.sort(sortNames);

		var group = [];
		var currentName = "";
		var currentGender = "";
		var idx = -1;

		for (var i = 0; i < all.length; ++i) {
			if (all[i].Name !== currentName || all[i].Gender !== currentGender) {
				var newEntry = { ID : i.toString(), Name : all[i].Name, Gender : all[i].Gender, Count : all[i].Count, History : [{Year : all[i].Year, Count : all[i].Count}]};
				group.push(newEntry);
				currentName = newEntry.Name;
				currentGender = newEntry.Gender;
				idx = group.length - 1;
			} else {
				group[idx].Count += all[i].Count;
				group[idx].History.push({Year : all[i].Year, Count : all[i].Count});
			}
		}

	    group.forEach(function(element) {
            element.History.sort(function(a, b) {
                return a.Year - b.Year;
            });
        });

		tgd.Utilities.Names.Grouped = group;
		
		
		
		console.log("Finished Processing Names");
		
		$("#lblTotalNum").text(tgd.Utilities.Names.Grouped.length + " names loaded");
		
		hidePromptScreen();
	    //displayNames(tgd.Utilities.Names.Grouped);
	}
	
	function displayNames() {
		console.log("Displaying names.");
		
		$("#panNames").empty();
		
		var names = tgd.Utilities.Names.Grouped;
		var genderFilter = $('[type="radio"]|[name="rblGender"]:checked').val();
		var nameFilter = $('#txtNameFilter').val();
		var sortBy = $('[type="radio"]|[name="rblSort"]:checked').val();
		
		$("#panNames").empty();

        if (genderFilter !== "B") {
			tgd.Utilities.Names.Filtered = names.filter(function(element){return element.Gender === genderFilter});
        } else {
        	tgd.Utilities.Names.Filtered = names;
        }

        if (nameFilter !== "") {
        	tgd.Utilities.Names.Filtered = tgd.Utilities.Names.Filtered.filter(function(element) { return element.Name.match(nameFilter, "i"); });
        }

        tgd.Utilities.Names.Filtered.sort((sortBy === "N") ? sortNames : sortCount);

        $("#lblFilterNum").text(tgd.Utilities.Names.Filtered.length + " names per filter");
		tgd.Utilities.Names.Filtered = tgd.Utilities.Names.Filtered.slice(0,999);
        if (tgd.Utilities.Names.Filtered.length < 1000 || confirm(tgd.Utilities.Names.Filtered.length + " names are returned from your filtering options.  Are you sure you want to attempt to display them?")) {
        	console.log("Rendering names next.");
        	setTimeout(function() { $("#panNames").html($("#nameTemplate").render(tgd.Utilities.Names.Filtered)); }, 0);
        }
	}

		</script>
		<style type="text/css">
			body {background: #000;margin: 0;font-size: 14pt;color: #fff;}
			#panMenu{background:#333;padding:.5em;border-bottom:solid 1px #09c;}
			#panPrompt{position:absolute;top:0;left:0;right:0;bottom:0;background:#000;text-align:center;z-index:1;}
			#menuToggleMenu,#menuToggleChart {text-align:right;padding:1em 0;}
			#menuToggleMenu span,#menuToggleChart span{background:#09c;padding:1em;}

			a{color:#09c;}

			.M{color:#abcdef;}
			.F{color:pink;}
			.hidden{display:none;}
			input[type='radio']{margin-right:3em;}
			input[type='button']{border:none;line-height:1em;padding:1em;color:#fff;background:#09c;font-size:1em;}
			input[type='text']{border:none;padding:.5em;color:#fff;background:#09c;}
			fieldset{background:#222;}


			.M,.F,.history{clear:both;}

			.F + div,.M + div{background:#222;}

			.M span:first-child,.F span:first-child,.history span:first-child{float:none;}
			.M span,.F span,.history span{float:right;}

			#panNames{-moz-column-width: 8em;-moz-column-gap: 1em;-moz-column-rule: 1px dashed #33B5E5;}

		</style>
	</head>
	<body onload="init();">
		<div id="panPrompt">
			<p>
				Use the files in the <a href="http://www.ssa.gov/oact/babynames/limits.html">National data (7Mb)</a> zip file.
			</p>
			<p>Select as many files from the download specified above.  It may take up to a minute to load if you choose several files.  You will then be presented with filtering options.  Choose your options and press 'Filter'.</p>
			<input id="fuNames" type="file" multiple="multiple" />
		</div>
		<div style="position:relative;">
			<div id="panMenu">
				<fieldset>
					<legend>Regular Expression Name Filtering</legend>
					<input id="txtNameFilter" type="text" size="20" />
				</fieldset>
				<fieldset>
					<legend>Gender</legend>
					<label for ="rbBoth">Both</label>
					<input type="radio" name="rblGender" id="rbBoth" value="B" checked="checked" />
					<label for ="rbMale">Male</label>
					<input type="radio" name="rblGender" id="rbMale" value="M" />
					<label for ="rbFemail">Female</label>
					<input type="radio" name="rblGender" id="rbFemail" value="F" />
				</fieldset>
				<fieldset>
					<legend>Sort By</legend>
					<label for ="rbName">Name</label>
					<input type="radio" name="rblSort" id="rbName" value="N" checked="checked" />
					<label for ="rbCount">Count</label>
					<input type="radio" name="rblSort" id="rbCount" value="C" />
				</fieldset>
				<fieldset>
					<legend>Submit</legend>
					<div id="lblTotalNum"></div>
					<div id="lblFilterNum"></div>
					<input id="btnFilter" type="button" value="Filter" />
				</fieldset>
				<fieldset>
					<legend>Chart</legend>
					<div class="reset" onclick="drawChart()">&#x21BB;</div>
					<div id="panChart" style="height:500px;width:600px;"></div>
				</fieldset>
			</div>
			<div id="menuToggleMenu" onclick="$('#panMenu').slideToggle('slow');">
				<span>Menu</span>
			</div>
		</div>
		<div id="panNames"></div>
	</body>
</html>
